package com.rongji.dfish.misc.util.json.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.parser.ParserConfig;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.rongji.dfish.base.util.json.impl.AbstractJsonBuilder;
import com.rongji.dfish.base.util.Utils;

import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

/**
 * Json对象构建器采用fastjson实现
 * @author lamontYu
 * @since DFish5.0
 */
public class JsonBuilder4Fastjson extends AbstractJsonBuilder {
    
    static {
        // 因安全漏洞需设置安全模式,涉及到autoType的业务可能有问题
        ParserConfig.getGlobalInstance().setSafeMode(true);
    }

    @Override
    public void setDateFormat(String dateFormat) {
        super.setDateFormat(dateFormat);
        // FIXME fastjson全局设置日期格式,这个写法有问题,定制化的写法应该考虑实现方案
        JSON.DEFFAULT_DATE_FORMAT = dateFormat;
    }

    @Override
    public String toJson(Object obj) {
        return JSON.toJSONString(obj, SerializerFeature.WriteDateUseDateFormat);
    }

    @Override
    public <T> T parseObject(String json, Class<T> objClass) {
        if (Utils.isEmpty(json)) {
            return null;
        }
        return JSON.parseObject(json, objClass);
    }

    @Override
    public <T> List<T> parseArray(String json, Class<T> objClass) {
        if (Utils.isEmpty(json)) {
            return new ArrayList<>(0);
        }
        return JSON.parseArray(json, objClass);
    }

    @Override
    public Map<String, String> parseAsStringPairs(String json) throws Exception {
        JSONObject jsonObject = JSON.parseObject(json);
        LinkedHashMap<String, String> ret = new LinkedHashMap<>(jsonObject.size());
        visit4StringPairs(jsonObject, null, ret);
        return ret;
    }

    private void visit4StringPairs(Object obj, String prefix, LinkedHashMap<String, String> ret) {
        if (obj instanceof JSONObject) {
            JSONObject jsonObject = (JSONObject) obj;
            for (String key : jsonObject.keySet()) {
                String currentKey = prefix == null ? key : (prefix + "." + key);
                visit4StringPairs(jsonObject.get(key), currentKey, ret);
            }
        } else if (obj instanceof JSONArray) {
            JSONArray jsonArray = (JSONArray) obj;
            for (int i = 0; i < jsonArray.size(); i++) {
                String currentKey = prefix == null ? String.valueOf(i) : (prefix + "." + i);
                visit4StringPairs(jsonArray.get(i), currentKey, ret);
            }
        } else {
            ret.put(prefix, String.valueOf(obj));
        }
    }

    @Override
    public Object parseObject(String json) throws Exception {
        Object jsonObject = JSON.parse(json);
        return visit(jsonObject);
    }

    private Object visit(Object obj) {
        if (obj instanceof JSONObject) {
            JSONObject jsonObject = (JSONObject) obj;
            Map<String, Object> ret = new LinkedHashMap<>(jsonObject.size());
            for (String key : jsonObject.keySet()) {
                ret.put(key, visit(jsonObject.get(key)));
            }
            return ret;
        } else if (obj instanceof JSONArray) {
            JSONArray jsonArray = (JSONArray) obj;
            List<Object> ret = new ArrayList<>(jsonArray.size());
            ;
            for (int i = 0; i < jsonArray.size(); i++) {
                ret.add(visit(jsonArray.get(i)));
            }
            return ret;
        } else {
            return obj;
        }
    }
}
